#include "filebased.h"

#include "earthquake_global.h"

#include <QFile>
#include <QDataStream>
#include <QString>

ExaVersion FileBased::m_version = EXA_VER_1_0_0;
ExaFileFormat FileBased::m_file_format = EXA_FILE_FORMAT_BINARY;

FileBased::FileBased()
{

}

string FileBased::fileObjDescriptor ( void ) const
{
    ExaFileObj obj_current = fileObj();
    switch (obj_current)
    {
    case EXA_FILE_OBJ_TEMPIRITORNOL:
        return "Stati Limite Sismici"; break;
    case EXA_FILE_OBJ_SPECPARAML:
        return "Parametri Spettrali"; break;
    case EXA_FILE_OBJ_SPECDESIGNL:
        return "Spettri di Progetto"; break;
    case EXA_FILE_OBJ_SEISMICLANDMARKS:
        return "Capisaldi Sismici"; break;
    case EXA_FILE_OBJ_STRATIGRAPHY:
        return "Stratigrafia"; break;
    case EXA_FILE_OBJ_TOPOGRAPHY:
        return "Topografia"; break;
    case EXA_FILE_OBJ_DATCAPISALDI:
        return "Analisi degli spettri"; break;
    case EXA_FILE_OBJ_DATPROGETTO:
        return "Progetto"; break;
    case EXA_FILE_OBJ_OUTCAPISALDI:
        return "Output spettri di progetto"; break;
    default:
        return "";
    }
}

string FileBased::fileExt ( ExaFileFormat f, ExaVersion v ) const
{
    ExaFileObj obj_current = fileObj();

    if ( f == EXA_FILE_FORMAT_CURRENT )
        f = m_file_format;

    if ( v == EXA_VER_CURRENT )
        v = m_version;

    if ( v == EXA_VER_1_0_0 )
    {
        if ( f == EXA_FILE_FORMAT_BINARY )
        {
            switch (obj_current)
            {
            case EXA_FILE_OBJ_TEMPIRITORNOL:
                return "sls"; break;
            case EXA_FILE_OBJ_SPECPARAML:
                return "spd"; break;
            case EXA_FILE_OBJ_SEISMICLANDMARKS:
                return "slm"; break;
            case EXA_FILE_OBJ_SPECDESIGNL:
                return "sdd"; break;
            case EXA_FILE_OBJ_STRATIGRAPHY:
                return "stg"; break;
            case EXA_FILE_OBJ_TOPOGRAPHY:
                return "tpg"; break;
            case EXA_FILE_OBJ_DATCAPISALDI:
                return "spe"; break;
            case EXA_FILE_OBJ_DATPROGETTO:
                return "prj"; break;
            case EXA_FILE_OBJ_PFILELIST:
                return "pfl"; break;
            case EXA_FILE_OBJ_OUTCAPISALDI:
                return "osd"; break;
            default:
                return "";
            }
        }
    }
}

quint32 FileBased::fileMagic ( ExaFileFormat f, ExaVersion v) const
{
    ExaFileObj obj_current = fileObj();

    if ( f == EXA_FILE_FORMAT_CURRENT )
        f = m_file_format;

    if ( v == EXA_VER_CURRENT )
        v = m_version;

    if ( v == EXA_VER_1_0_0 )
    {
        if ( f == EXA_FILE_FORMAT_BINARY )
        {
            switch (obj_current)
            {
            case EXA_FILE_OBJ_TEMPIRITORNOL:
                return EXA_MN_1_0_0_BIN_SLS; break;
            case EXA_FILE_OBJ_SPECPARAML:
                return EXA_MN_1_0_0_BIN_SPD; break;
            case EXA_FILE_OBJ_SPECDESIGNL:
                return EXA_MN_1_0_0_BIN_SDD; break;
            case EXA_FILE_OBJ_SEISMICLANDMARKS:
                return EXA_MN_1_0_0_BIN_SLM; break;
            case EXA_FILE_OBJ_STRATIGRAPHY:
                return EXA_MN_1_0_0_BIN_STG; break;
            case EXA_FILE_OBJ_TOPOGRAPHY:
                return EXA_MN_1_0_0_BIN_TPG; break;
            case EXA_FILE_OBJ_DATCAPISALDI:
                return EXA_MN_1_0_0_BIN_SPE; break;
            case EXA_FILE_OBJ_DATPROGETTO:
                return EXA_MN_1_0_0_BIN_PRJ; break;
            case EXA_FILE_OBJ_PFILELIST:
                return EXA_MN_1_0_0_BIN_PFL; break;
            case EXA_FILE_OBJ_OUTCAPISALDI:
                return EXA_MN_1_0_0_BIN_OSD; break;
            default:
                return EXA_MN_ERR_OBJ;
            }
        }
        else return EXA_MN_ERR_FORMAT;
    }
    else return EXA_MN_ERR_VERSION;
}

ExaFileFormat FileBased::fileFormat ( void )
{
    return m_file_format;
}

void FileBased::fileFormat ( ExaFileFormat f )
{
    m_file_format = f;
}

ExaVersion FileBased::fileVersion ( void )
{
    return m_version;
}

void FileBased::fileVersion ( ExaVersion v )
{
    m_version = v;
}

ExaFileErr FileBased::fileControl (
        const string& file_name,
        ExaFileOpenMode om
        ) const
{
    quint32   magic_obj = fileMagic();
    if (magic_obj == EXA_MN_ERR_OBJ)
        return EXA_FILE_ERR_MN_OBJ;
    if (magic_obj == EXA_MN_ERR_FORMAT)
        return EXA_FILE_ERR_MN_FORMAT;
    if (magic_obj == EXA_MN_ERR_VERSION)
        return EXA_FILE_ERR_MN_VERSION;

    quint32 version_obj = fileVersion();

    switch (version_obj)
    {
        case EXA_VER_1_0_0:
        {
            // controllo lo stato di apertura del file
            QFile file(QSTR(file_name));
            if ( om == EXA_FILE_OM_READ_ONLY )
            {
                if (!QFile::exists(QSTR(file_name)))
                    return EXA_FILE_ERR_DOESNTEXISTS;

                if (!file.open(QIODevice::ReadOnly))
                    return EXA_FILE_ERR_READONLY;

                // apro intestazione dati binari
                QDataStream in(&file);
                in.setVersion(QDataStream::Qt_4_5);

                quint32 magic_file, version_file;
                in >> magic_file >> version_file;

                // controllo della intestazione
                if (magic_file != magic_obj)
                    return EXA_FILE_ERR_UNKNOWN;

                if (version_file != version_obj)
                    return EXA_FILE_ERR_RECENT;
            }
            if ( om == EXA_FILE_OM_WRITE_ONLY )
            {
                if (!file.open(QIODevice::WriteOnly))
                    return EXA_FILE_ERR_WRITEONLY;
            }
        } break;
        default:
            return EXA_FILE_ERR_MN_UNKNOWN;
    }
}

void FileBased::fileReset ( void )
{
    m_version = EXA_VER_1_0_0;
    m_file_format = EXA_FILE_FORMAT_BINARY;
}
